//! 联系方式服务
//! 提供联系方式管理相关的业务逻辑

use crate::client::EntityClient;
use crate::models::contact::*;
use crate::models::view_entities::*;
use crate::models::*;
use crate::services::{QueryBuilder, utils};
use crate::{Result, PartyModError};
use std::collections::HashMap;
use chrono::{DateTime, Utc};

/// 联系方式服务
#[derive(Clone)]
pub struct ContactService {
    client: EntityClient,
}

/// 完整的联系方式信息
#[derive(Debug, Clone)]
pub struct ContactInfo {
    pub party_id: String,
    pub contact_mech_id: String,
    pub contact_type: ContactType,
    pub purpose: String,
    pub is_primary: bool,
    pub from_date: DateTime<Utc>,
    pub thru_date: Option<DateTime<Utc>>,
    pub verified: bool,
    pub allow_solicitation: bool,
    // 邮政地址信息
    pub postal_address: Option<PostalAddressInfo>,
    // 电话信息
    pub phone_info: Option<PhoneInfo>,
    // 邮箱信息
    pub email_info: Option<EmailInfo>,
}

/// 联系方式类型
#[derive(Debug, Clone, PartialEq)]
pub enum ContactType {
    PostalAddress,
    TelecomNumber,
    EmailAddress,
    WebAddress,
    Other(String),
}

/// 邮政地址信息
#[derive(Debug, Clone)]
pub struct PostalAddressInfo {
    pub to_name: Option<String>,
    pub attn_name: Option<String>,
    pub address1: Option<String>,
    pub address2: Option<String>,
    pub city: Option<String>,
    pub state_province: Option<String>,
    pub postal_code: Option<String>,
    pub country: Option<String>,
    pub formatted_address: String,
}

/// 电话信息
#[derive(Debug, Clone)]
pub struct PhoneInfo {
    pub country_code: Option<String>,
    pub area_code: Option<String>,
    pub contact_number: String,
    pub extension: Option<String>,
    pub formatted_number: String,
}

/// 邮箱信息
#[derive(Debug, Clone)]
pub struct EmailInfo {
    pub email_address: String,
    pub is_verified: bool,
}

impl ContactService {
    /// 创建新的联系方式服务
    pub fn new(client: EntityClient) -> Self {
        Self { client }
    }

    /// 添加邮政地址
    pub async fn add_postal_address(
        &mut self,
        party_id: &str,
        address1: &str,
        address2: Option<&str>,
        city: &str,
        state_province: Option<&str>,
        postal_code: Option<&str>,
        country: &str,
        purpose: &str,
        is_primary: bool
    ) -> Result<String> {
        let contact_mech_id = utils::generate_contact_mech_id();
        
        // 创建ContactMech
        let contact_mech = ContactMech {
            contact_mech_id: contact_mech_id.clone(),
            contact_mech_type_id: "POSTAL_ADDRESS".to_string(),
            info_string: Some(format!("{}, {}, {}", address1, city, country)),
        };
        
        let contact_mech_data = contact_mech.to_data_row();
        self.client.insert_data("ContactMech", contact_mech_data).await?;
        
        // 创建PostalAddress
        let postal_address = PostalAddress {
            contact_mech_id: contact_mech_id.clone(),
            to_name: None,
            attn_name: None,
            address1: Some(address1.to_string()),
            address2: address2.map(|s| s.to_string()),
            house_number: None,
            house_number_ext: None,
            directions: None,
            city: Some(city.to_string()),
            city_geo_id: None,
            postal_code: postal_code.map(|s| s.to_string()),
            postal_code_ext: None,
            country_geo_id: Some(country.to_string()),
            state_province_geo_id: state_province.map(|s| s.to_string()),
            county_geo_id: None,
            municipality_geo_id: None,
            postal_code_geo_id: None,
            geo_point_id: None,
        };
        
        let postal_address_data = postal_address.to_data_row();
        self.client.insert_data("PostalAddress", postal_address_data).await?;
        
        // 创建PartyContactMech
        let party_contact_mech = PartyContactMech {
            party_id: party_id.to_string(),
            contact_mech_id: contact_mech_id.clone(),
            from_date: Utc::now(),
            thru_date: None,
            role_type_id: None,
            allow_solicitation: Some(true),
            extension: None,
            verified: Some(false),
            comments: None,
            years_with_contact_mech: None,
            months_with_contact_mech: None,
        };
        
        let party_contact_mech_data = party_contact_mech.to_data_row();
        self.client.insert_data("PartyContactMech", party_contact_mech_data).await?;
        
        // 添加联系方式用途
        self.add_contact_purpose(&party_id, &contact_mech_id, purpose).await?;
        
        // 如果是主要地址，更新其他地址为非主要
        if is_primary {
            self.set_primary_contact(&party_id, &contact_mech_id, "POSTAL_ADDRESS").await?;
        }
        
        Ok(contact_mech_id)
    }

    /// 添加电话号码
    pub async fn add_phone_number(
        &mut self,
        party_id: &str,
        country_code: Option<&str>,
        area_code: Option<&str>,
        contact_number: &str,
        extension: Option<&str>,
        purpose: &str,
        is_primary: bool
    ) -> Result<String> {
        let contact_mech_id = utils::generate_contact_mech_id();
        
        // 格式化电话号码
        let formatted_number = self.format_phone_number(country_code, area_code, contact_number, extension);
        
        // 创建ContactMech
        let contact_mech = ContactMech {
            contact_mech_id: contact_mech_id.clone(),
            contact_mech_type_id: "TELECOM_NUMBER".to_string(),
            info_string: Some(formatted_number.clone()),
        };
        
        let contact_mech_data = contact_mech.to_data_row();
        self.client.insert_data("ContactMech", contact_mech_data).await?;
        
        // 创建TelecomNumber
        let telecom_number = TelecomNumber {
            contact_mech_id: contact_mech_id.clone(),
            country_code: country_code.map(|s| s.to_string()),
            area_code: area_code.map(|s| s.to_string()),
            contact_number: contact_number.to_string(),
            ask_for_name: None,
        };
        
        let telecom_number_data = telecom_number.to_data_row();
        self.client.insert_data("TelecomNumber", telecom_number_data).await?;
        
        // 创建PartyContactMech
        let party_contact_mech = PartyContactMech {
            party_id: party_id.to_string(),
            contact_mech_id: contact_mech_id.clone(),
            from_date: Utc::now(),
            thru_date: None,
            role_type_id: None,
            allow_solicitation: Some(true),
            extension: extension.map(|s| s.to_string()),
            verified: Some(false),
            comments: None,
            years_with_contact_mech: None,
            months_with_contact_mech: None,
        };
        
        let party_contact_mech_data = party_contact_mech.to_data_row();
        self.client.insert_data("PartyContactMech", party_contact_mech_data).await?;
        
        // 添加联系方式用途
        self.add_contact_purpose(&party_id, &contact_mech_id, purpose).await?;
        
        // 如果是主要电话，更新其他电话为非主要
        if is_primary {
            self.set_primary_contact(&party_id, &contact_mech_id, "TELECOM_NUMBER").await?;
        }
        
        Ok(contact_mech_id)
    }

    /// 添加邮箱地址
    pub async fn add_email_address(
        &mut self,
        party_id: &str,
        email_address: &str,
        purpose: &str,
        is_primary: bool
    ) -> Result<String> {
        // 验证邮箱格式
        if !utils::is_valid_email(email_address) {
            return Err(Box::new(PartyModError::InvalidData("Invalid email format".to_string())));
        }
        
        let contact_mech_id = utils::generate_contact_mech_id();
        
        // 创建ContactMech
        let contact_mech = ContactMech {
            contact_mech_id: contact_mech_id.clone(),
            contact_mech_type_id: "EMAIL_ADDRESS".to_string(),
            info_string: Some(email_address.to_string()),
        };
        
        let contact_mech_data = contact_mech.to_data_row();
        self.client.insert_data("ContactMech", contact_mech_data).await?;
        
        // 创建PartyContactMech
        let party_contact_mech = PartyContactMech {
            party_id: party_id.to_string(),
            contact_mech_id: contact_mech_id.clone(),
            from_date: Utc::now(),
            thru_date: None,
            role_type_id: None,
            allow_solicitation: Some(true),
            extension: None,
            verified: Some(false),
            comments: None,
            years_with_contact_mech: None,
            months_with_contact_mech: None,
        };
        
        let party_contact_mech_data = party_contact_mech.to_data_row();
        self.client.insert_data("PartyContactMech", party_contact_mech_data).await?;
        
        // 添加联系方式用途
        self.add_contact_purpose(&party_id, &contact_mech_id, purpose).await?;
        
        // 如果是主要邮箱，更新其他邮箱为非主要
        if is_primary {
            self.set_primary_contact(&party_id, &contact_mech_id, "EMAIL_ADDRESS").await?;
        }
        
        Ok(contact_mech_id)
    }

    /// 添加联系方式用途
    async fn add_contact_purpose(
        &mut self,
        party_id: &str,
        contact_mech_id: &str,
        purpose: &str
    ) -> Result<()> {
        let party_contact_mech_purpose = PartyContactMechPurpose {
            party_id: party_id.to_string(),
            contact_mech_id: contact_mech_id.to_string(),
            contact_mech_purpose_type_id: purpose.to_string(),
            from_date: Utc::now(),
            thru_date: None,
        };
        
        let data = party_contact_mech_purpose.to_data_row();
        self.client.insert_data("PartyContactMechPurpose", data).await?;
        Ok(())
    }

    /// 设置主要联系方式
    async fn set_primary_contact(
        &mut self,
        party_id: &str,
        contact_mech_id: &str,
        contact_type: &str
    ) -> Result<()> {
        // 这里可以实现设置主要联系方式的逻辑
        // 在OFBiz中，通常通过ContactMechPurposeType来标识主要联系方式
        // 比如PRIMARY_PHONE, PRIMARY_EMAIL等
        
        let primary_purpose = match contact_type {
            "POSTAL_ADDRESS" => "PRIMARY_LOCATION",
            "TELECOM_NUMBER" => "PRIMARY_PHONE",
            "EMAIL_ADDRESS" => "PRIMARY_EMAIL",
            _ => "PRIMARY",
        };
        
        self.add_contact_purpose(party_id, contact_mech_id, primary_purpose).await?;
        Ok(())
    }

    /// 获取Party的所有联系方式
    pub async fn get_party_contacts(&mut self, party_id: &str) -> Result<Vec<ContactInfo>> {
        let conditions = vec![
            crate::models::QueryCondition {
                field: "partyId".to_string(),
                operator: "EQUALS".to_string(),
                value: party_id.to_string(),
                logic: "AND".to_string(),
            }
        ];
        
        let rows = self.client.query_data("PartyContactDetailByPurpose", None, Some(conditions.into_iter().map(|c| c.into()).collect()), None, None, None).await?;
        
        let mut contacts = Vec::new();
        for row in rows {
            let contact_detail = PartyContactDetailByPurpose::from_data_row(&row.fields)?;
            
            let contact_type = match contact_detail.contact_mech_type_id.as_str() {
                "POSTAL_ADDRESS" => ContactType::PostalAddress,
                "TELECOM_NUMBER" => ContactType::TelecomNumber,
                "EMAIL_ADDRESS" => ContactType::EmailAddress,
                "WEB_ADDRESS" => ContactType::WebAddress,
                other => ContactType::Other(other.to_string()),
            };
            
            let purpose_type_id = contact_detail.contact_mech_purpose_type_id.clone();
            let mut contact_info = ContactInfo {
                party_id: contact_detail.party_id,
                contact_mech_id: contact_detail.contact_mech_id,
                contact_type: contact_type.clone(),
                purpose: contact_detail.contact_mech_purpose_type_id,
                is_primary: self.is_primary_purpose(&purpose_type_id),
                from_date: contact_detail.from_date,
                thru_date: contact_detail.thru_date,
                verified: contact_detail.verified.unwrap_or(false),
                allow_solicitation: contact_detail.allow_solicitation.unwrap_or(false),
                postal_address: None,
                phone_info: None,
                email_info: None,
            };
            
            // 根据联系方式类型填充详细信息
            match contact_type {
                ContactType::PostalAddress => {
                    let formatted_address = utils::format_address(
                        contact_detail.address1.as_deref(),
                        contact_detail.address2.as_deref(),
                        contact_detail.city.as_deref(),
                        contact_detail.state_geo_name.as_deref(),
                        contact_detail.postal_code.as_deref(),
                        contact_detail.country_geo_name.as_deref()
                    );
                    
                    contact_info.postal_address = Some(PostalAddressInfo {
                        to_name: contact_detail.to_name,
                        attn_name: contact_detail.attn_name,
                        address1: contact_detail.address1,
                        address2: contact_detail.address2,
                        city: contact_detail.city,
                        state_province: contact_detail.state_geo_name,
                        postal_code: contact_detail.postal_code,
                        country: contact_detail.country_geo_name,
                        formatted_address,
                    });
                },
                ContactType::TelecomNumber => {
                    let formatted_number = self.format_phone_number(
                        contact_detail.country_code.as_deref(),
                        contact_detail.area_code.as_deref(),
                        &contact_detail.contact_number.as_ref().unwrap_or(&String::new()),
                        contact_detail.extension.as_deref()
                    );
                    
                    contact_info.phone_info = Some(PhoneInfo {
                        country_code: contact_detail.country_code.clone(),
                        area_code: contact_detail.area_code.clone(),
                        contact_number: contact_detail.contact_number.unwrap_or_default(),
                        extension: contact_detail.extension.clone(),
                        formatted_number,
                    });
                },
                ContactType::EmailAddress => {
                    contact_info.email_info = Some(EmailInfo {
                        email_address: contact_detail.info_string.unwrap_or_default(),
                        is_verified: contact_detail.verified.unwrap_or(false),
                    });
                },
                _ => {}
            }
            
            contacts.push(contact_info);
        }
        
        Ok(contacts)
    }

    /// 获取Party的邮政地址
    pub async fn get_party_postal_addresses(&mut self, party_id: &str) -> Result<Vec<PartyAndPostalAddress>> {
        let conditions = vec![
            crate::models::QueryCondition {
                field: "partyId".to_string(),
                operator: "EQUALS".to_string(),
                value: party_id.to_string(),
                logic: "AND".to_string(),
            },
            crate::models::QueryCondition {
                field: "contactMechTypeId".to_string(),
                operator: "EQUALS".to_string(),
                value: "POSTAL_ADDRESS".to_string(),
                logic: "AND".to_string(),
            }
        ];
        
        let rows = self.client.query_data("PartyAndPostalAddress", None, Some(conditions.into_iter().map(|c| c.into()).collect()), None, None, None).await?;
        
        let mut addresses = Vec::new();
        for row in rows {
            let address = PartyAndPostalAddress::from_data_row(&row.fields)?;
            addresses.push(address);
        }
        
        Ok(addresses)
    }

    /// 获取主要邮政地址
    pub async fn get_primary_postal_address(&mut self, party_id: &str) -> Result<Option<PartyAndPostalAddress>> {
        let conditions = vec![
            crate::models::QueryCondition {
                field: "partyId".to_string(),
                operator: "EQUALS".to_string(),
                value: party_id.to_string(),
                logic: "AND".to_string(),
            },
            crate::models::QueryCondition {
                field: "contactMechTypeId".to_string(),
                operator: "EQUALS".to_string(),
                value: "POSTAL_ADDRESS".to_string(),
                logic: "AND".to_string(),
            },
            crate::models::QueryCondition {
                field: "contactMechPurposeTypeId".to_string(),
                operator: "EQUALS".to_string(),
                value: "PRIMARY_LOCATION".to_string(),
                logic: "AND".to_string(),
            }
        ];
        
        let rows = self.client.query_data("PartyAndPostalAddress", None, Some(conditions.into_iter().map(|c| c.into()).collect()), None, None, None).await?;
        
        if let Some(row) = rows.first() {
            let address = PartyAndPostalAddress::from_data_row(&row.fields)?;
            Ok(Some(address))
        } else {
            Ok(None)
        }
    }

    /// 更新联系方式
    pub async fn update_contact_mech(
        &mut self,
        contact_mech_id: &str,
        new_info: &str
    ) -> Result<()> {
        let conditions = vec![
            crate::models::QueryCondition {
                field: "contactMechId".to_string(),
                operator: "EQUALS".to_string(),
                value: contact_mech_id.to_string(),
                logic: "AND".to_string(),
            }
        ];
        
        let rows = self.client.query_data("ContactMech", None, Some(conditions.into_iter().map(|c| c.into()).collect()), None, None, None).await?;
        
        if let Some(row) = rows.first() {
            let mut contact_mech = ContactMech::from_data_row(&row.fields)?;
            contact_mech.info_string = Some(new_info.to_string());
            
            let data = contact_mech.to_data_row();
            let update_conditions = vec![
                crate::models::QueryCondition {
                    field: "contactMechId".to_string(),
                    operator: "EQUALS".to_string(),
                    value: contact_mech_id.to_string(),
                    logic: "AND".to_string(),
                }
            ];
            
            self.client.update_data("ContactMech", data, update_conditions.into_iter().map(|c| c.into()).collect()).await?;
        }
        
        Ok(())
    }

    /// 删除联系方式
    pub async fn remove_contact_mech(
        &mut self,
        party_id: &str,
        contact_mech_id: &str
    ) -> Result<()> {
        // 设置PartyContactMech的结束日期
        let conditions = vec![
            crate::models::QueryCondition {
                field: "partyId".to_string(),
                operator: "EQUALS".to_string(),
                value: party_id.to_string(),
                logic: "AND".to_string(),
            },
            crate::models::QueryCondition {
                field: "contactMechId".to_string(),
                operator: "EQUALS".to_string(),
                value: contact_mech_id.to_string(),
                logic: "AND".to_string(),
            }
        ];
        
        let rows = self.client.query_data("PartyContactMech", None, Some(conditions.into_iter().map(|c| c.into()).collect()), None, None, None).await?;
        
        for row in rows {
            let mut party_contact_mech = PartyContactMech::from_data_row(&row.fields)?;
            party_contact_mech.thru_date = Some(Utc::now());
            
            let data = party_contact_mech.to_data_row();
            let update_conditions = vec![
                crate::models::QueryCondition {
                    field: "partyId".to_string(),
                    operator: "EQUALS".to_string(),
                    value: party_id.to_string(),
                    logic: "AND".to_string(),
                },
                crate::models::QueryCondition {
                    field: "contactMechId".to_string(),
                    operator: "EQUALS".to_string(),
                    value: contact_mech_id.to_string(),
                    logic: "AND".to_string(),
                }
            ];
            
            self.client.update_data("PartyContactMech", data, update_conditions.into_iter().map(|c| c.into()).collect()).await?;
        }
        
        Ok(())
    }

    /// 验证联系方式
    pub async fn verify_contact_mech(
        &mut self,
        party_id: &str,
        contact_mech_id: &str
    ) -> Result<()> {
        let conditions = vec![
            crate::entity_service::QueryCondition {
                field: "partyId".to_string(),
                operator: "EQUALS".to_string(),
                value: party_id.to_string(),
                logic: "AND".to_string(),
            },
            crate::entity_service::QueryCondition {
                field: "contactMechId".to_string(),
                operator: "EQUALS".to_string(),
                value: contact_mech_id.to_string(),
                logic: "AND".to_string(),
            }
        ];
        
        let rows = self.client.query_data("PartyContactMech", None, Some(conditions.into_iter().map(|c| c.into()).collect()), None, None, None).await?;
        
        for row in rows {
            let mut party_contact_mech = PartyContactMech::from_data_row(&row.fields)?;
            party_contact_mech.verified = Some(true);
            
            let data = party_contact_mech.to_data_row();
            let update_conditions = vec![
                crate::entity_service::QueryCondition {
                    field: "partyId".to_string(),
                    operator: "EQUALS".to_string(),
                    value: party_id.to_string(),
                    logic: "AND".to_string(),
                },
                crate::entity_service::QueryCondition {
                    field: "contactMechId".to_string(),
                    operator: "EQUALS".to_string(),
                    value: contact_mech_id.to_string(),
                    logic: "AND".to_string(),
                }
            ];
            
            self.client.update_data("PartyContactMech", data, update_conditions.into_iter().map(|c| c.into()).collect()).await?;
        }
        
        Ok(())
    }

    /// 格式化电话号码
    fn format_phone_number(
        &self,
        country_code: Option<&str>,
        area_code: Option<&str>,
        contact_number: &str,
        extension: Option<&str>
    ) -> String {
        let mut formatted = String::new();
        
        if let Some(cc) = country_code {
            formatted.push_str(&format!("+{} ", cc));
        }
        
        if let Some(ac) = area_code {
            formatted.push_str(&format!("({}) ", ac));
        }
        
        formatted.push_str(contact_number);
        
        if let Some(ext) = extension {
            formatted.push_str(&format!(" ext. {}", ext));
        }
        
        formatted
    }

    /// 检查是否为主要用途
    fn is_primary_purpose(&self, purpose: &str) -> bool {
        matches!(purpose, "PRIMARY_LOCATION" | "PRIMARY_PHONE" | "PRIMARY_EMAIL" | "PRIMARY")
    }
}

impl std::fmt::Display for ContactType {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            ContactType::PostalAddress => write!(f, "Postal Address"),
            ContactType::TelecomNumber => write!(f, "Phone Number"),
            ContactType::EmailAddress => write!(f, "Email Address"),
            ContactType::WebAddress => write!(f, "Web Address"),
            ContactType::Other(s) => write!(f, "{}", s),
        }
    }
}